package net.cathackers.devel.scmp.chat.impl;

import org.apache.log4j.Logger;

import net.cathackers.devel.scmp.auth.interfaces.UserID;
import net.cathackers.devel.scmp.chat.impl.xmpp.iqcomponent.interfaces.Processor;
import net.cathackers.devel.scmp.chat.interfaces.ChatManager;
import net.cathackers.devel.scmp.chat.interfaces.ChatSession;
import net.cathackers.devel.scmp.exceptions.NotAllowedException;
import net.cathackers.devel.scmp.factories.SCMPFactory;
import net.cathackers.devel.scmp.xmpp.Packet;
import net.cathackers.devel.scmp.xmpp.PresencePacket;
import net.cathackers.devel.scmp.xmpp.RosterPacket;

public class OnlineDeliveryProcessor implements Processor<Packet> {
    private ChatManager chatManager_;
    private Logger logger_;

    public OnlineDeliveryProcessor() {
	logger_ = SCMPFactory.getLogger(this);
	this.chatManager_ = SCMPFactory.getChatManager();
    }

    public void process(Packet packet) {
	UserID userID = packet.getTo();
	// check if the to is defined in the packet
	if (userID != null) {
	    ChatSession[] userSession = chatManager_.getChatSession(userID);

	    if (packet instanceof RosterPacket || packet instanceof PresencePacket) {

		if (userSession.length != 0) {
		    for (ChatSession session : userSession) {
			if (session.getRosterRequested() == true) {
			    packet.setTo(session.getUserID().getGeneralUserID());
			    session.deliverPacket(packet);
			    logger_.info("delivering the Packet to online user that has requested the roster");
			}
		    }
		}

	    } else if (userSession.length != 0) {
		    logger_.debug("Found " + userSession.length + " session(s) for userID" + userID.getCanonicalName());
		    for (ChatSession session : userSession) {
			packet.setTo(session.getUserID());
			packet.setBaseStreamID(session.getSessionID());
			logger_.info("delivering the packet to online user with sessionID " + session.getSessionID() +":"  + packet.toXML());
			session.deliverPacket(packet);
		    }
	    }

	    // route the packet based on the stream ID
	} else {
	    // route it to the receiver using SessionID
	    logger_.debug("routing the packet will be based on streamID");

	    String sessionID = packet.getBaseStreamID();
	    logger_.debug("Sending packet to user with SessionID " + sessionID);
	    ChatSession userSession = chatManager_.getChatSession(sessionID);
	    if (userSession != null) {
		try {
		    userSession.getConnection().deliver(packet);
		} catch (NotAllowedException e) {
		    logger_.error("Not allowed");
		}

	    } else {
		// TODO drop the packet or send an error packet
		logger_.warn("Cannot send a message to offline user");
		logger_.info("the packet is droped");
	    }
	}
    }
}
